#include <iostream>
#include <string>
#include <functional>
#include "Util/FunctionTraits.h"

using namespace std;
using namespace toolkit;

// 普通函数
int add(int a, int b) {
    return a + b;
}

// 带有多个参数的函数
string concatenate(int a, double b, const char* c) {
    return to_string(a) + to_string(b) + string(c);
}

// 类成员函数
class TestClass {
public:
    void memberFunc(int a, double b) {
        cout << "成员函数被调用: " << a << ", " << b << endl;
    }
    
    int constMemberFunc(int a) const {
        return a * 2;
    }
};

// 函数对象
struct Functor {
    double operator()(int a, float b) {
        return a + b;
    }
};

// 递归打印参数类型
template<typename F, size_t I>
void printArgsType() {
    if constexpr (I < FunctionTraits<F>::arity) {
        cout << "    参数 " << I << " 类型: " 
             << typeid(typename FunctionTraits<F>::template args<I>::type).name() << endl;
        printArgsType<F, I+1>();
    }
}

// 辅助函数：打印函数特性信息
template<typename F>
void printFunctionInfo(const string& name) {
    cout << "函数名: " << name << endl;
    cout << "  参数数量: " << FunctionTraits<F>::arity << endl;
    cout << "  返回类型: " << typeid(typename FunctionTraits<F>::returnType).name() << endl;
    
    // 如果有参数，打印每个参数的类型
    if constexpr (FunctionTraits<F>::arity > 0) {
        cout << "  参数类型:" << endl;
        printArgsType<F, 0>();
    } else {
        cout << "  无参数" << endl;
    }
    cout << endl;
}

int main() {
    cout << "开始测试 FunctionTraits..." << endl << endl;
    
    // 测试普通函数
    printFunctionInfo<decltype(add)>("add");
    
    // 测试带有多个参数的函数
    printFunctionInfo<decltype(concatenate)>("concatenate");
    
    // 测试函数指针
    using AddFuncPtr = int(*)(int, int);
    printFunctionInfo<AddFuncPtr>("函数指针 (int(*)(int, int))");
    
    // 测试 std::function
    using StdFunc = std::function<string(int, double, const char*)>;
    printFunctionInfo<StdFunc>("std::function<string(int, double, const char*)>");
    
    // 测试成员函数
    using MemberFunc = void (TestClass::*)(int, double);
    printFunctionInfo<MemberFunc>("TestClass::memberFunc");
    
    // 测试 const 成员函数
    using ConstMemberFunc = int (TestClass::*)(int) const;
    printFunctionInfo<ConstMemberFunc>("TestClass::constMemberFunc");
    
    // 测试函数对象
    printFunctionInfo<Functor>("Functor");
    
    // 测试 lambda 表达式
    auto lambda = [](int a, string b) -> bool { return a > 0 && !b.empty(); };
    printFunctionInfo<decltype(lambda)>("Lambda [](int, string) -> bool");
    
    // 实际使用示例
    cout << "实际使用示例:" << endl;
    
    // 获取函数的第一个参数类型
    using FirstArgType = FunctionTraits<decltype(concatenate)>::args<0>::type;
    FirstArgType firstArg = 42;
    cout << "concatenate 的第一个参数类型变量: " << firstArg << endl;
    
    // 使用 stlFunctionType 创建 std::function
    FunctionTraits<decltype(add)>::stlFunctionType addFunc = add;
    cout << "通过 stlFunctionType 调用 add: " << addFunc(10, 20) << endl;
    
    return 0;
}